﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System;
using DMS.Redis;
using SqlSugar.Template.IService;
using SqlSugar.Template.Models;
using Microsoft.Extensions.Configuration;
using DMS.Auth.Oauth2;
using Microsoft.AspNetCore.Authorization;
using DMS.Common.Model.Result;
using System.Threading.Tasks;
using SqlSugar.Template.IService.Result;
using IdentityModel;
using StackExchange.Redis;
using Microsoft.Extensions.Caching.Distributed;
using System.Configuration;
using SqlSugar;
using System.Linq;
using NetTaste;
using System.Security.Principal;
using System.Reflection;
using SqlSugar.Template.Extensions;

namespace BookApi.Controllers
{


    [ApiController]

    [Route("api/[controller]")]
    public class AuthController : ControllerBase
    {
        private readonly IConfiguration _configuration;
        private readonly IUseService _useService;
        private readonly IDatabase _redis;
        // 使用依赖注入的方式来获取配置信息
        public AuthController(IDatabase redis, IConfiguration configuration, IUseService useService)
        {
            _redis= redis;
            _configuration = configuration;
            _useService = useService;
        }

        // 用户登录方法
        [HttpPost("login")]
        //[Authorize]
        public async Task<ResponseResult<UseResult>> Login([FromBody] Use loginDto)
        {
            ResponseResult<UseResult> result = new() { data = new UseResult() };
            // 简单的身份验证逻辑，仅为演示用途
            if (loginDto == null) {               
                    result.errno = 1;
                result.errmsg = "未找到相关数据";
                return result;
            }
            if (string.IsNullOrWhiteSpace(loginDto.Account)|| string.IsNullOrWhiteSpace(loginDto.PassWord))
            {
                result.errno = 1;
                result.errmsg = "账号或密码不能为空";
                return result;
            }
        var PassWrodreslut =  CryptographyHelper.GetMD5Hash(loginDto.PassWord);            
            result =  await     _useService.GetUseByAccountAndPwdAsync(loginDto.Account, PassWrodreslut);
            if (result.data!=null)
            {          
                result.data.Token= GenerateJwtToken(loginDto);
                var redisKey = $"user:token:{loginDto.Account}";
                var redisValue = result.data.Token;
                var expiresInMinutes = Convert.ToDouble(_configuration["JwtSetting:ExpiresInMinutes"]);
                _redis.StringSet(redisKey, redisValue, TimeSpan.FromMinutes(expiresInMinutes));
            }
            // 否则返回未经授权的状态
            return result;
        }

        /// <summary>
        /// 注销
        /// </summary>
        /// <returns></returns>
        [HttpPost("logout")]
       [Authorize]
        public  async Task<ResponseResult> Logout()
        {
            ResponseResult result = new()
            {
                data = new()
            };
            var account = User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
            var redisKey = $"user:token:{account}";
            if (!string.IsNullOrEmpty(account))
            {
                _redis.KeyDelete(redisKey);
                result.data = "Successfully logged out";
            }
            else {
                // 如果用户名为空，可能表示用户信息不完整或请求未正确验证。
                // 根据您的应用逻辑，您可能希望返回一个错误消息或状态码。
                result.errno = 1;
                result.data = "Failed to log out: No session found for user";
            }
          
            return  result;
        }

        // 生成 JWT 令牌的方法
        private string GenerateJwtToken(Use use)
        {
            // 获取签名密钥
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtSetting:SecretKey"]));
            // 创建签名凭据
            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

            // 声明信息，包含用户标识
            var claims = new[]
            {
            new Claim(JwtRegisteredClaimNames.Sub, use.Account),  // 用户标识
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())  // 令牌唯一标识
        };
       
              // 创建 JWT 令牌
              var token = new JwtSecurityToken(_configuration["JwtSetting:Issuer"],
                _configuration["JwtSetting:Audience"],
                claims,
                expires: DateTime.Now.AddMinutes(Convert.ToDouble( _configuration["JwtSetting:ExpiresInMinutes"])),  // 令牌过期时间为30分钟
                signingCredentials: credentials);  // 使用签名凭据对令牌签名

            // 返回令牌字符串
            return new JwtSecurityTokenHandler().WriteToken(token);
        }
    }
}